#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
@author: yinzhuoqun
@site: http://zhuoqun.info/
@email: yin@zhuoqun.info
@time: 2025/4/18 16:33
"""

# pip install flask
import redis
from contextlib import contextmanager


class RedisServer:
    """
    优化后的Redis连接管理类，支持连接池、异常处理和多种操作
    """
    _global_pool = None  # 单例连接池

    def __init__(self, host='localhost', port=6379, password=None, db=0, max_connections=100):
        self.host = host
        self.port = port
        self.password = password
        self.db = db
        self.pool = self._get_connection_pool(max_connections)
        self.redis = redis.Redis(connection_pool=self.pool)

    def _get_connection_pool(self, max_connections):
        """获取全局单例连接池"""
        if RedisServer._global_pool is None:
            RedisServer._global_pool = redis.ConnectionPool(
                host=self.host, port=self.port, password=self.password,
                db=self.db, decode_responses=True, max_connections=max_connections
            )
        return RedisServer._global_pool

    @contextmanager
    def get_connection(self):
        """上下文管理器，自动处理连接异常"""
        try:
            yield self.redis
        except redis.RedisError as e:
            raise RuntimeError(f"Redis操作失败: {e}")

    def close(self):
        """关闭连接池（通常不需要手动调用）"""
        if RedisServer._global_pool:
            RedisServer._global_pool.disconnect()


# 使用示例
if __name__ == "__main__":
    # 初始化连接（密码可选）
    redis_server = RedisServer(host='127.0.0.1', password='', db=0)

    # 示例1：字符串操作
    with redis_server.get_connection() as r:
        r.set("user:1001", "Alice")  # 存储字符串
        name = r.get("user:1001")  # 读取字符串
        print(f"获取字符串: {name}")  # 输出: Alice

    # 示例2：哈希表操作
    with redis_server.get_connection() as r:
        r.hset("employee:2001", mapping={"name": "Bob", "age": "30"})  # 存储哈希
        employee = r.hgetall("employee:2001")  # 读取哈希
        print(f"获取哈希表: {employee}")  # 输出: {'name': 'Bob', 'age': '30'}

    # 示例3：列表操作（支持批量）
    with redis_server.get_connection() as r:
        r.rpush("tasks", "task1", "task2")  # 存储列表
        tasks = r.lrange("tasks", 0, -1)  # 读取全部列表
        print(f"获取列表: {tasks}")  # 输出: ['task1', 'task2']

    # 示例4：带过期时间的键（自动删除）
    with redis_server.get_connection() as r:
        r.setex("temp_session", 10, "expiring_data")  # 10秒后过期
        print(r.get("temp_session"))  # 立即获取有效，10秒后返回None

    # 关闭连接池（可选，程序退出时会自动清理）
    redis_server.close()
